/*******************************************************************************
 * Copyright (c) 2008 Sylvain Sicard.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Sylvain Sicard - initial API and implementation
 ******************************************************************************/
package fr.jade.fraclite.control.state;

import java.lang.reflect.Field;

import org.objectweb.fractal.api.factory.InstantiationException;

import fr.jade.fraclite.InitializationContext;
import fr.jade.fraclite.api.ComponentState;
import fr.jade.fraclite.api.Controller;
import fr.jade.fraclite.api.State;
import fr.jade.fraclite.api.control.StateController;

public class BasicStateController implements Controller, StateController {

  Object innerImpl;
  Class<?> innerImplClass;
  
  @Override
  public void initFcController(InitializationContext ic) throws InstantiationException {
    innerImpl = ic.content;
    if(innerImpl != null){
      this.innerImplClass = innerImpl.getClass();
    }
  }
  
  @Override
  public State getState() {
    State s = new State();
    if(innerImpl != null){
      for(Field f : innerImplClass.getDeclaredFields()){
        if(f.isAnnotationPresent(ComponentState.class)){
          String fieldName = f.getName();
          try {
            f.setAccessible(true);
            Object fieldValue = f.get(innerImpl);
            s.setFieldValue(fieldName, fieldValue);
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    }
    return s;
  }

  @Override
  public void setState(State state) {
    if(innerImpl != null){
      for(String fieldName : state.listFiels()){
        try {
          Field f = innerImplClass.getDeclaredField(fieldName);
          Object fieldValue = state.getFieldValue(fieldName);
          f.setAccessible(true);
          f.set(innerImpl, fieldValue);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
  }

}
